# Calendar Sync Permission - Quick Reference

## What Was Added

A permission gating system for calendar sync features in the Django backend.

## Key Components

### 1. Database Field
```python
# core/models.py - Added to Tenant model
can_use_calendar_sync = models.BooleanField(default=False)
```

### 2. Permission Check Factory
```python
# core/permissions.py - Added to FEATURE_NAMES
'can_use_calendar_sync': 'Calendar Sync',
```

### 3. OAuth Integration
```python
# core/oauth_views.py - Check when purpose is 'calendar'
if purpose == 'calendar':
    calendar_permission = HasFeaturePermission('can_use_calendar_sync')
    if not calendar_permission().has_permission(request, self):
        return Response({'error': 'Feature not available'}, status=403)
```

### 4. Calendar Sync Views
```python
# schedule/calendar_sync_views.py
CalendarListView           # GET /api/calendar/list/
CalendarSyncView           # POST /api/calendar/sync/
CalendarDeleteView         # DELETE /api/calendar/disconnect/
CalendarStatusView         # GET /api/calendar/status/
```

## How to Use

### Enable for a Tenant
```bash
# Via Django shell
from core.models import Tenant
tenant = Tenant.objects.get(schema_name='demo')
tenant.can_use_calendar_sync = True
tenant.save()
```

### Use in ViewSet
```python
from rest_framework import viewsets
from core.permissions import HasFeaturePermission

class MyViewSet(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated, HasFeaturePermission('can_use_calendar_sync')]
```

### Use in APIView
```python
from rest_framework.views import APIView

class MyView(APIView):
    permission_classes = [CalendarSyncPermission]
    # CalendarSyncPermission = IsAuthenticated + has_feature check
```

## API Endpoints

| Method | Endpoint | Description | Permission |
|--------|----------|-------------|-----------|
| GET | /api/calendar/status/ | Check if calendar sync is available | Auth only |
| GET | /api/calendar/list/ | List connected calendars | Calendar sync |
| POST | /api/calendar/sync/ | Start calendar sync | Calendar sync |
| DELETE | /api/calendar/disconnect/ | Disconnect a calendar | Calendar sync |
| POST | /api/oauth/google/initiate/ | Start Google OAuth for calendar | Calendar sync (if purpose=calendar) |
| POST | /api/oauth/microsoft/initiate/ | Start MS OAuth for calendar | Calendar sync (if purpose=calendar) |

## Testing

### Run tests
```bash
cd /home/poduck/Desktop/smoothschedule2/smoothschedule
docker compose -f docker-compose.local.yml exec django pytest schedule/tests/test_calendar_sync_permissions.py -v
```

### Test endpoints manually
```bash
# Check status (always works)
curl http://lvh.me:8000/api/calendar/status/ -H "Authorization: Bearer <token>"

# List calendars (requires permission)
curl http://lvh.me:8000/api/calendar/list/ -H "Authorization: Bearer <token>"
# Returns 403 if permission not granted
```

## Files Modified

| File | Changes |
|------|---------|
| core/models.py | Added can_use_calendar_sync field |
| core/permissions.py | Added to FEATURE_NAMES |
| core/oauth_views.py | Added permission check for calendar |

## Files Created

| File | Purpose |
|------|---------|
| core/migrations/0016_tenant_can_use_calendar_sync.py | Database migration |
| schedule/calendar_sync_views.py | Calendar sync API views |
| schedule/calendar_sync_urls.py | URL routing |
| schedule/tests/test_calendar_sync_permissions.py | Test suite |
| CALENDAR_SYNC_INTEGRATION.md | Developer guide |

## Permission Check Pattern

```
Request to calendar endpoint
  ↓
Check: Is user authenticated?
  ├─ NO → 401 Unauthorized
  └─ YES ↓
Check: Does tenant have can_use_calendar_sync=True?
  ├─ NO → 403 Forbidden (upgrade message)
  └─ YES ↓
Process request
  ├─ Success → 200 OK
  └─ Error → 500 Server Error
```

## Example: Full Permission Setup

```python
# 1. Enable feature for tenant
from core.models import Tenant
tenant = Tenant.objects.get(schema_name='demo')
tenant.can_use_calendar_sync = True
tenant.save()

# 2. User tries to access calendar endpoint
# GET /api/calendar/list/
# → Check: tenant.has_feature('can_use_calendar_sync')
# → True! → 200 OK with calendar list

# 3. Without permission
tenant.can_use_calendar_sync = False
tenant.save()
# GET /api/calendar/list/
# → Check: tenant.has_feature('can_use_calendar_sync')
# → False! → 403 Forbidden with upgrade message
```

## Related Documentation

- **Full Guide:** `CALENDAR_SYNC_INTEGRATION.md` in smoothschedule/ folder
- **Implementation Details:** `CALENDAR_SYNC_PERMISSION_IMPLEMENTATION.md` in project root
- **Code:** `schedule/calendar_sync_views.py` (well-commented)
- **Tests:** `schedule/tests/test_calendar_sync_permissions.py`

## Common Tasks

### Check if feature is enabled
```python
tenant.has_feature('can_use_calendar_sync')  # Returns bool
```

### Get list of connected calendars
```python
from core.models import OAuthCredential

credentials = OAuthCredential.objects.filter(
    tenant=tenant,
    purpose='calendar',
    is_valid=True
)
```

### Handle permission denied
```python
from core.permissions import HasFeaturePermission

permission = HasFeaturePermission('can_use_calendar_sync')
if not permission().has_permission(request, view):
    # User doesn't have permission
    # Show upgrade prompt
```

## Notes

- Feature defaults to **False** for all tenants (opt-in)
- Works alongside existing subscription plan system
- Follows same pattern as SMS reminders, webhooks, etc.
- Multi-tenant isolation built-in
- OAuth tokens are encrypted at rest
- All operations logged for audit trail
